"""
python多态有2种模式
    1. （原生支持）鸭子类型多态（Duck Typing Polymorphism） ;
    2. 抽象基类多态（ABC Polymorphism）
"""


# 😀😀 Duck Typing(鸭子类型)

# 🌟 核心思想
#  1.这是python 原生支持的，
#  2.核心思想： 如果它走起来像鸭子，叫起来像鸭子，那它就是鸭子。
#  3. Python 的多态不关心对象的“类型”或“继承关系”，只关心它是否具有某个方法或属性。只要接口一致，就可以被统一处理。

# 🌟 实现方式
# 通用函数，不关心类型
def make_it_speak(animal):
    print(animal.speak())  # 只要你有 speak() 方法，就能调用

class Dog:
    def speak(self):
        return "汪汪！"

class Cat:
    def speak(self):
        return "喵喵！"

class Robot:
    def speak(self):
        return "哔哔！"

# 使用
make_it_speak(Dog())    # 汪汪！
make_it_speak(Cat())    # 喵喵！
make_it_speak(Robot())  # 哔哔！✅ Robot 根本不是动物

# 🌟 核心机制
#   动态分派：调用 animal.speak() 时，Python 在运行时查找对象的 speak 方法。
#   hasattr() / getattr()：你可以手动检查或获取方法。
#   EAFP 原则：“It’s Easier to Ask for Forgiveness than Permission”（请求宽恕比请求许可更容易）

# 🌟 优点
#   任何类，只要实现相同方法，就能参与多态，无需耦合。
#   类之间无需继承或实现接口，结构松散，易于扩展。
#   代码少，逻辑清晰，符合“Pythonic”风格。
#   新增类型无需修改已有代码（符合开闭原则）。

# 🌟 缺点
#   如果对象没有该方法，只有在运行时才会报 AttributeError。
#   其他开发者不知道“哪些方法是必须实现的”。
#   类型提示不足，自动补全和静态检查困难。
#   方法名拼错或参数不一致时难以发现。

print("\n-------------------------------------------------------\n")

# 😀😀 ABC(鸭子类型)
# 🌟 核心思想
#   解决鸭子类型问题
#   通过 abc 模块定义抽象基类（Abstract Base Class），强制子类实现某些方法，从而提供一种“接口契约”。
#   这更像 Java/C++ 的风格，强调规范、安全和可维护性。


# 🌟 实现方式
#   使用 ABC 和 @abstractmethod 装饰器。
from abc import ABC, abstractmethod

class Animal(ABC):
    @abstractmethod
    def speak(self) -> str:
        """所有动物都必须会叫"""
        pass

    @abstractmethod
    def move(self) -> str:
        pass

class Dog(Animal):
    def speak(self) -> str:
        return "汪汪！"

    def move(self) -> str:
        return "跑"

# ❌ 错误：Cat 没有实现 move
class Cat(Animal):
    def speak(self) -> str:
        return "喵喵！"
    # 忘记实现 move → 实例化时报错

dog = Dog()  # ✅ 可以实例化
# cat = Cat()  # ❌ TypeError: Can't instantiate abstract class


# 🌟 核心机制
# ABC：标记类为抽象基类。
# @abstractmethod：标记方法为抽象方法，子类必须重写。
# 实例化检查：如果子类未实现所有抽象方法，在实例化时就会报错，而不是运行时调用时报错。

# 🌟 优缺点与Duck type相反

# 🌟 推荐策略：“鸭子类型为主，ABC 为辅”
# 1. 大多数情况下使用鸭子类型
#   小项目、工具脚本、数据处理、Web API。
#   你希望代码简洁、灵活、易于扩展。
# 2. 在以下情况使用 ABC
#   构建框架或库：你需要定义清晰的插件接口。
#   团队协作：需要明确契约，避免“我忘了实现哪个方法”。
#   大型项目：提高可维护性和可读性。
#   需要 isinstance() 检查：比如注册处理器、路由分发。


# ❤️❤️❤️❤️总结 ：
#   Python 的多态之美，在于它既允许你“随心所欲”地调用方法（鸭子类型），也允许你“立下规矩”来保障安全（ABC/Protocol）。
#   真正的“完美”，是知道何时该自由，何时该约束。